#!/bin/sh
set -e

# This script checks whether NVIDIA GPUs that are only supported by a
# previous legacy driver are present in the system.
# Unfortunately, there were several reports that this does not work
# on some systems because lspci hangs. That seems to be a hardware
# dependent issue. See e.g. #819869 for details.
#
# A possible workaround is to reboot with 'acpi=off' added to the
# kernel boot options in the GRUB configuration.
#
# Alternatively this check can be disabled by preseeding:
#   echo "nvidia-driver/check-for-unsupported-gpu boolean false" | debconf-set-selections


. /usr/share/debconf/confmodule

LEGACY_DRIVER="nvidia-tesla-470-driver"
LEGACY_PCIIDS="
10DE0FC0
10DE0FC1
10DE0FC2
10DE0FC6
10DE0FC8
10DE0FC9
10DE0FCD
10DE0FCE
10DE0FD1
10DE0FD2
10DE0FD3
10DE0FD4
10DE0FD5
10DE0FD8
10DE0FD9
10DE0FDF
10DE0FE0
10DE0FE1
10DE0FE2
10DE0FE3
10DE0FE4
10DE0FE9
10DE0FEA
10DE0FEC
10DE0FED
10DE0FEE
10DE0FF3
10DE0FF6
10DE0FF8
10DE0FF9
10DE0FFA
10DE0FFB
10DE0FFC
10DE0FFD
10DE0FFE
10DE0FFF
10DE1001
10DE1004
10DE1005
10DE1007
10DE1008
10DE100A
10DE100C
10DE1021
10DE1022
10DE1023
10DE1024
10DE1026
10DE1027
10DE1028
10DE1029
10DE102A
10DE102D
10DE103A
10DE103C
10DE1180
10DE1183
10DE1184
10DE1185
10DE1187
10DE1188
10DE1189
10DE118A
10DE118E
10DE118F
10DE1193
10DE1194
10DE1195
10DE1198
10DE1199
10DE119A
10DE119D
10DE119E
10DE119F
10DE11A0
10DE11A1
10DE11A2
10DE11A3
10DE11A7
10DE11B4
10DE11B6
10DE11B7
10DE11B8
10DE11BA
10DE11BC
10DE11BD
10DE11BE
10DE11C0
10DE11C2
10DE11C3
10DE11C4
10DE11C5
10DE11C6
10DE11C8
10DE11CB
10DE11E0
10DE11E1
10DE11E2
10DE11E3
10DE11FA
10DE11FC
10DE1280
10DE1281
10DE1282
10DE1284
10DE1286
10DE1287
10DE1288
10DE1289
10DE128B
10DE1290
10DE1291
10DE1292
10DE1293
10DE1295
10DE1296
10DE1298
10DE1299
10DE129A
10DE12B9
10DE12BA
10DE137D
10DE1BB3
10DE1DF5
10DE1F09
"

if [ "$DEBUG_NVIDIA_LEGACY_CHECK" = "yes" ]; then
	set -x
fi

find_unsupported_gpus()
{
	if [ -n "$OVERRIDE_NVIDIA_LEGACY_CHECK_UNSUPPORTED_DEVICES" ]; then
		echo "$OVERRIDE_NVIDIA_LEGACY_CHECK_UNSUPPORTED_DEVICES"
		return
	fi

	# Check for GPUs that are only supported up to $LEGACY_DRIVER
	if lspci --version > /dev/null 2>&1; then
		lspci -mn \
		| awk '{ gsub("\"",""); if ($2 == "0300") { print $1 " " $3$4 } }' \
		| tr '[:lower:]' '[:upper:]' \
		| while read dev id
		do
			for x in $LEGACY_PCIIDS
			do
				if [ "$x" = "$id" ]; then
					echo "$dev"
					break
				fi
			done
		done
	fi
}


check_for_unsupported_gpus()
{
	# allow to disable the check via preseeding
	db_get nvidia-driver/check-for-unsupported-gpu
	test "$RET" = "true" || return 0

	(
		sleep 30 &
		sleeppid=$!
		trap 'kill $sleeppid 2>/dev/null || true' TERM
		trap ':' EXIT
		wait $sleeppid
		echo "Checking for legacy NVIDIA GPUs appears to hang, try rebooting with 'acpi=off'" >&2
		echo "added to the kernel boot options in the GRUB configuration." >&2
	) &
	msgpid=$!

	UNSUPPORTED_DEVICES="$(find_unsupported_gpus)"
	UNSUPPORTED="$(for dev in $UNSUPPORTED_DEVICES ; do lspci -nn -s "$dev" ; done)"

	kill $msgpid 2>/dev/null || true

	test -n "$UNSUPPORTED_DEVICES" || return 0

	db_subst nvidia-driver/install-even-if-unsupported-gpu-exists vendor "NVIDIA"
	db_subst nvidia-driver/install-even-if-unsupported-gpu-exists driver "#NVIDIA#-driver"
	db_subst nvidia-driver/install-even-if-unsupported-gpu-exists legacy_driver "$LEGACY_DRIVER"
	db_subst nvidia-driver/install-even-if-unsupported-gpu-exists free_name "Nouveau"
	db_subst nvidia-driver/install-even-if-unsupported-gpu-exists free_driver "xserver-xorg-video-nouveau"
	db_subst nvidia-driver/install-even-if-unsupported-gpu-exists unsupported-device "$(echo "$UNSUPPORTED" | sed -r 's/$/; /' | tr -d '\n' | sed -r 's/; $//')"

	# ensure the question is asked again unless it was accepted previously for the same $LEGACY_DRIVER
	db_get nvidia-driver/supported-in-legacy-driver-name
	if [ "$RET" != "$LEGACY_DRIVER" ]; then
		db_reset nvidia-driver/install-even-if-unsupported-gpu-exists
		db_fset nvidia-driver/install-even-if-unsupported-gpu-exists seen false
	fi

	db_input high nvidia-driver/install-even-if-unsupported-gpu-exists || true
	db_go

	echo "*** The following unsupported devices are present in the machine:"
	echo "$UNSUPPORTED"

	db_get nvidia-driver/install-even-if-unsupported-gpu-exists
	if [ "$RET" = "false" ]; then
		echo "Aborting nvidia driver installation."
		exit 1
	fi

	# remember the answer until $LEGACY_DRIVER changes
	db_set nvidia-driver/supported-in-legacy-driver-name "$LEGACY_DRIVER"
}


if [ "$1" = "install" ] || [ "$1" = "upgrade" ]; then

	check_for_unsupported_gpus

fi

#DEBHELPER#
